# 贪吃蛇小游戏
import pygame
from pygame.locals import *
import sys
import random

# 自定义颜色常量
BLACK = 0,0,0
WHITE = 255,255,255
RED = 255,0,0
GREEN = 0,255,0
BLUE = 0,0,255

class Snack:
	def __init__(self):
		self.head = (2,1) # 初始化头部位置
		self.body = [(1,1)] # 初始化蛇身
		self.direction = "right" # 初始化方向
		self.old_direction = "right" # 初始化上一次方向
		self.alive = True # 活着
		self.front = (0,0)

	def go(self):
		self.changeDirction()
		self.getFront()
		if self.askAlive():
			self.body.append(self.head)
			self.head = self.front
			return True
		return False

	# 判断下一步的方向
	def changeDirction(self):
		d = {"up":"down","down":"up","left":"right","right":"left"}
		if d[self.direction] == self.old_direction:
			self.direction = self.old_direction
		self.old_direction = self.direction

	# 获取头部的下一个位置
	def getFront(self):
		x,y = self.head
		if self.direction == "up":
			self.front = (x,y-1)
		elif self.direction == "down":
			self.front = (x,y+1)
		elif self.direction == "left":
			self.front = (x-1,y)
		elif self.direction == "right":
			self.front = (x+1,y)

	# 判断下一步走出去是否还存活
	def askAlive(self):
		x,y = self.front
		if x < 1 or x > 16 or y < 1 or y > 12:
			return False
		if self.front in self.body:
			return False
		return True

class Map:
	def __init__(self,width,height,food):
		self.width = width
		self.height = height
		self.food = food
		self.back_color = WHITE

	# 生成新的食物
	def newFood(self,head,body):
		i = 0
		while i < 100:
			x = random.randint(1,16)
			y = random.randint(1,12)
			if (x,y) != head and (x,y) not in body:
				self.food = (x,y)
				return True
			i += 1
		else:
			self.food = (0,0)
			return False

def key_control(snack_temp,pause):
	'''键盘控制函数'''
	# 执行退出操作
	for event in pygame.event.get():
		if event.type == QUIT:
			print("exit()")
			exit()
	# 获取按键信息
	pressed_keys = pygame.key.get_pressed()
	# 做出判断
	if pressed_keys[K_LEFT] or pressed_keys[K_a]:
		snack_temp.direction = "left"
	elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
		snack_temp.direction = "right"
	elif pressed_keys[K_UP] or pressed_keys[K_w]:
		snack_temp.direction = "up"
	elif pressed_keys[K_DOWN] or pressed_keys[K_s]:
		snack_temp.direction = "down"

	if pressed_keys[K_p]:
		pause = not pause

def draws(dot,color,screen):
	pygame.draw.rect(screen,color,((dot[0]-1)*50+1,(dot[1]-1)*50+1,48,48))

def main():
	'''主程序函数'''
	pygame.init()
	# 初始化一张地图和小蛇
	map = Map(800,600,(5,4))
	snack = Snack()
	screen = pygame.display.set_mode((map.width,map.height)) # 创建游戏窗口 800*600
	pygame.display.set_caption("贪吃蛇") # 设置导航栏名称

	fclock = pygame.time.Clock() # 设置游戏初始时间
	times = 0 # 设置一个时间戳
	pause = False # 未暂停
	ticktime = 500
	while True:
		key_control(snack,pause) # 执行键盘控制

		if times >= 100:
			if snack.go():
				if snack.head == map.food:
					snack.alive = map.newFood(snack.head,snack.body)
				else:
					snack.body.pop(0)
			else:
				map.back_color = BLACK
				pygame.display.set_caption("game over")
				return
			times = 0
		else:
			times += 1

		screen.fill(map.back_color)	
		draws(map.food,RED,screen)
		for b in snack.body:
			draws(b,BLUE,screen)
		draws(snack.head,GREEN,screen)
		
		snackLen = len(snack.body)
		if snackLen <= 5:
			ticktime = 500
		elif snackLen < 20:
			ticktime = snackLen * 100
		else:
			ticktime = 2000
		fclock.tick(ticktime)
		pygame.display.update()

# 判断当前是否是主运行程序，并调用
if __name__ == '__main__':
	main()